package constants

import (
	"pids-cloud-server/entity"
	"sync"
	"time"
)

// HostAlarm 主机告警信息
type HostAlarm struct {
	// 主机IP
	HostIP string
	// 告警状态 (ACTIVE/INACTIVE)
	Status entity.AlarmActive
	// 告警信息映射 (告警类型 -> 告警信息)
	Alarms map[entity.AlarmType]entity.AlarmInfo
	// 最后更新时间
	LastUpdated time.Time
}

// AlarmManager 告警管理器
type AlarmManager struct {
	mu         sync.RWMutex
	hostAlarms map[string]*HostAlarm // 主机IP -> 主机告警信息
	syncLock   sync.Mutex            // 用于同步操作的锁
	isSyncing  bool                  // 是否正在进行同步
}

// 全局告警管理器实例
var GlobalAlarmManager = NewAlarmManager()

// NewAlarmManager 创建一个新的告警管理器
func NewAlarmManager() *AlarmManager {
	return &AlarmManager{
		hostAlarms: make(map[string]*HostAlarm),
		isSyncing:  false,
	}
}

// SetAlarm 设置主机的告警信息
func (m *AlarmManager) SetAlarm(hostIP string, alarmInfo entity.AlarmInfo) {
	m.mu.Lock()
	defer m.mu.Unlock()

	// 获取或创建主机告警信息
	hostAlarm, exists := m.hostAlarms[hostIP]
	if !exists {
		hostAlarm = &HostAlarm{
			HostIP:      hostIP,
			Status:      entity.INACTIVE,
			Alarms:      make(map[entity.AlarmType]entity.AlarmInfo),
			LastUpdated: time.Now(),
		}
		m.hostAlarms[hostIP] = hostAlarm
	}

	// 更新告警信息
	if alarmInfo.Status == entity.ACTIVE {
		hostAlarm.Alarms[alarmInfo.Type] = alarmInfo
		hostAlarm.Status = entity.ACTIVE
	} else {
		// 如果告警状态为非活跃，删除该告警
		delete(hostAlarm.Alarms, alarmInfo.Type)

		// 检查是否还有其他活跃告警
		if len(hostAlarm.Alarms) == 0 {
			hostAlarm.Status = entity.INACTIVE
		}
	}

	hostAlarm.LastUpdated = time.Now()
}

// RemoveAlarm 移除主机的特定类型告警
func (m *AlarmManager) RemoveAlarm(hostIP string, alarmType entity.AlarmType) {
	m.mu.Lock()
	defer m.mu.Unlock()

	hostAlarm, exists := m.hostAlarms[hostIP]
	if !exists {
		return
	}

	// 删除特定类型的告警
	delete(hostAlarm.Alarms, alarmType)

	// 更新主机状态
	if len(hostAlarm.Alarms) == 0 {
		hostAlarm.Status = entity.INACTIVE
	}

	hostAlarm.LastUpdated = time.Now()
}

// GetHostStatus 获取主机的告警状态
func (m *AlarmManager) GetHostStatus(hostIP string) entity.AlarmActive {
	m.mu.RLock()
	defer m.mu.RUnlock()

	hostAlarm, exists := m.hostAlarms[hostIP]
	if !exists {
		return entity.INACTIVE
	}

	return hostAlarm.Status
}

// GetAllHostStatus 获取所有主机的告警状态
func (m *AlarmManager) GetAllHostStatus() map[string]entity.AlarmActive {
	m.mu.RLock()
	defer m.mu.RUnlock()

	result := make(map[string]entity.AlarmActive)
	for hostIP, hostAlarm := range m.hostAlarms {
		result[hostIP] = hostAlarm.Status
	}

	return result
}

// GetAlarm 获取主机的特定类型告警
func (m *AlarmManager) GetAlarm(hostIP string, alarmType entity.AlarmType) (entity.AlarmInfo, bool) {
	m.mu.RLock()
	defer m.mu.RUnlock()

	hostAlarm, exists := m.hostAlarms[hostIP]
	if !exists {
		return entity.AlarmInfo{}, false
	}

	alarm, found := hostAlarm.Alarms[alarmType]
	return alarm, found
}

// GetAllAlarms 获取主机的所有告警
func (m *AlarmManager) GetAllAlarms(hostIP string) map[entity.AlarmType]entity.AlarmInfo {
	m.mu.RLock()
	defer m.mu.RUnlock()

	hostAlarm, exists := m.hostAlarms[hostIP]
	if !exists {
		return nil
	}

	// 创建一个副本以避免并发问题
	result := make(map[entity.AlarmType]entity.AlarmInfo)
	for alarmType, alarm := range hostAlarm.Alarms {
		result[alarmType] = alarm
	}

	return result
}

// GetAllActiveHosts 获取所有有活跃告警的主机
func (m *AlarmManager) GetAllActiveHosts() []string {
	m.mu.RLock()
	defer m.mu.RUnlock()

	var activeHosts []string
	for hostIP, hostAlarm := range m.hostAlarms {
		if hostAlarm.Status == entity.ACTIVE {
			activeHosts = append(activeHosts, hostIP)
		}
	}

	return activeHosts
}

// GetAllInactiveHosts 获取所有没有活跃告警的主机
func (m *AlarmManager) GetAllInactiveHosts() []string {
	m.mu.RLock()
	defer m.mu.RUnlock()

	var inactiveHosts []string
	for hostIP, hostAlarm := range m.hostAlarms {
		if hostAlarm.Status == entity.INACTIVE {
			inactiveHosts = append(inactiveHosts, hostIP)
		}
	}

	return inactiveHosts
}

// HostWithAlarms 带告警信息的主机数据结构
type HostWithAlarms struct {
	HostIP      string                                // 主机IP
	Status      entity.AlarmActive                    // 告警状态
	Alarms      map[entity.AlarmType]entity.AlarmInfo // 告警信息映射
	LastUpdated time.Time                             // 最后更新时间
	AlarmCount  int                                   // 告警数量
}

// GetAllHostsWithAlarmStatus 获取所有激活告警状态和关闭告警状态的主机数据
func (m *AlarmManager) GetAllHostsWithAlarmStatus() (activeHosts []HostWithAlarms, inactiveHosts []HostWithAlarms) {
	m.mu.RLock()
	defer m.mu.RUnlock()

	for hostIP, hostAlarm := range m.hostAlarms {
		// 创建告警信息副本
		alarmsCopy := make(map[entity.AlarmType]entity.AlarmInfo)
		for alarmType, alarm := range hostAlarm.Alarms {
			alarmsCopy[alarmType] = alarm
		}

		// 构建主机告警数据
		hostWithAlarms := HostWithAlarms{
			HostIP:      hostIP,
			Status:      hostAlarm.Status,
			Alarms:      alarmsCopy,
			LastUpdated: hostAlarm.LastUpdated,
			AlarmCount:  len(hostAlarm.Alarms),
		}

		// 根据状态分类
		if hostAlarm.Status == entity.ACTIVE {
			activeHosts = append(activeHosts, hostWithAlarms)
		} else {
			inactiveHosts = append(inactiveHosts, hostWithAlarms)
		}
	}

	return activeHosts, inactiveHosts
}

// HasActiveAlarm 检查主机是否有活跃告警
func (m *AlarmManager) HasActiveAlarm(hostIP string) bool {
	return m.GetHostStatus(hostIP) == entity.ACTIVE
}

// GetAlarmCount 获取主机的告警数量
func (m *AlarmManager) GetAlarmCount(hostIP string) int {
	m.mu.RLock()
	defer m.mu.RUnlock()

	hostAlarm, exists := m.hostAlarms[hostIP]
	if !exists {
		return 0
	}

	return len(hostAlarm.Alarms)
}

// ClearAllAlarms 清除主机的所有告警
func (m *AlarmManager) ClearAllAlarms(hostIP string) {
	m.mu.Lock()
	defer m.mu.Unlock()

	hostAlarm, exists := m.hostAlarms[hostIP]
	if !exists {
		return
	}

	hostAlarm.Alarms = make(map[entity.AlarmType]entity.AlarmInfo)
	hostAlarm.Status = entity.INACTIVE
	hostAlarm.LastUpdated = time.Now()
}

// GetAllAlarmsByType 获取特定类型的所有告警
func (m *AlarmManager) GetAllAlarmsByType(alarmType entity.AlarmType) map[string]entity.AlarmInfo {
	m.mu.RLock()
	defer m.mu.RUnlock()

	result := make(map[string]entity.AlarmInfo)
	for hostIP, hostAlarm := range m.hostAlarms {
		if alarm, found := hostAlarm.Alarms[alarmType]; found {
			result[hostIP] = alarm
		}
	}

	return result
}

// StartSync 开始同步操作，返回是否成功获取同步锁
func (m *AlarmManager) StartSync() bool {
	if !m.syncLock.TryLock() {
		return false
	}

	m.isSyncing = true
	return true
}

// EndSync 结束同步操作
func (m *AlarmManager) EndSync() {
	m.isSyncing = false
	m.syncLock.Unlock()
}

// IsSyncing 检查是否正在进行同步
func (m *AlarmManager) IsSyncing() bool {
	return m.isSyncing
}

// BatchSetAlarms 批量设置告警信息（用于同步）
func (m *AlarmManager) BatchSetAlarms(alarms []entity.AlarmInfo) {
	m.mu.Lock()
	defer m.mu.Unlock()

	// 创建一个临时映射，用于跟踪每个主机的告警
	hostAlarmsMap := make(map[string]map[entity.AlarmType]entity.AlarmInfo)

	// 处理所有活跃告警
	for _, alarm := range alarms {
		if alarm.Status != entity.ACTIVE {
			continue
		}

		// 确保主机的告警映射已初始化
		if _, exists := hostAlarmsMap[alarm.HostIP]; !exists {
			hostAlarmsMap[alarm.HostIP] = make(map[entity.AlarmType]entity.AlarmInfo)
		}

		// 存储告警信息
		hostAlarmsMap[alarm.HostIP][alarm.Type] = alarm
	}

	// 更新告警管理器
	for hostIP, alarms := range hostAlarmsMap {
		hostAlarm, exists := m.hostAlarms[hostIP]
		if !exists {
			hostAlarm = &HostAlarm{
				HostIP:      hostIP,
				Status:      entity.INACTIVE,
				Alarms:      make(map[entity.AlarmType]entity.AlarmInfo),
				LastUpdated: time.Now(),
			}
			m.hostAlarms[hostIP] = hostAlarm
		}

		// 清除现有告警
		hostAlarm.Alarms = make(map[entity.AlarmType]entity.AlarmInfo)

		// 添加新告警
		for alarmType, alarm := range alarms {
			hostAlarm.Alarms[alarmType] = alarm
		}

		// 更新状态
		if len(hostAlarm.Alarms) > 0 {
			hostAlarm.Status = entity.ACTIVE
		} else {
			hostAlarm.Status = entity.INACTIVE
		}

		hostAlarm.LastUpdated = time.Now()
	}

	// 处理没有活跃告警的主机
	for hostIP, hostAlarm := range m.hostAlarms {
		if _, exists := hostAlarmsMap[hostIP]; !exists {
			hostAlarm.Alarms = make(map[entity.AlarmType]entity.AlarmInfo)
			hostAlarm.Status = entity.INACTIVE
			hostAlarm.LastUpdated = time.Now()
		}
	}
}

// GetLastUpdated 获取主机告警信息的最后更新时间
func (m *AlarmManager) GetLastUpdated(hostIP string) time.Time {
	m.mu.RLock()
	defer m.mu.RUnlock()

	hostAlarm, exists := m.hostAlarms[hostIP]
	if !exists {
		return time.Time{}
	}

	return hostAlarm.LastUpdated
}
